package com.weifly.weistock.module.stockbill;

import com.weifly.weistock.bo.record.RecordPairBO;
import com.weifly.weistock.core.common.StockException;
import com.weifly.weistock.core.constant.StockBillBusinessNameEnum;
import com.weifly.weistock.core.util.WeistockUtils;
import com.weifly.weistock.module.stockbill.bo.StockRecordBO;

import java.util.ArrayList;
import java.util.List;

public class CalcStockContext {

    private int pairIndex = 1; // pair的索引值
    private List<RecordPairBO> pairList = new ArrayList<>(); // 匹配的pair列表

    private StockRecordBO currRecord; // 当前记录
    private StockBillBusinessNameEnum currBusinessName; // 当前记录ot
    private int currTradeNumber; // 当前记录 剩余未配对数量

    public void initRecord(StockRecordBO recordBO) {
        StockBillBusinessNameEnum businessName = recordBO.getBusinessName();
        if (StockBillConverter.isCloseRecord(recordBO)) {
            this.pairList.clear();
            this.currRecord = recordBO;
            this.currBusinessName = businessName;
            this.currTradeNumber = recordBO.getTradeNumber();
        } else {
            throw new StockException("不支持的businessName, " + businessName.getName());
        }
    }

    public void buildPair(StockRecordBO preRecord) {
        // 没有“未配对”记录
        if (this.currTradeNumber <= 0) {
            return;
        }

        // 不是 证券买入记录
        if (!StockBillConverter.isOpenRecord(preRecord)) {
            return;
        }

        // 没有成交数量
        if (preRecord.getTradeNumber() <= 0) {
            return;
        }

        // preRecord已配对完成
        int preNotPairNumber = StockBillConverter.getNotPairNumber(preRecord);
        if (preNotPairNumber <= 0) {
            return;
        }

        // 创建配对
        int pairNumber = this.currTradeNumber <= preNotPairNumber ? this.currTradeNumber : preNotPairNumber;
        RecordPairBO pairInfo = new RecordPairBO();
        pairInfo.setIndex(this.pairIndex);
        pairInfo.setNumber(pairNumber);
        this.addPairToRecord(preRecord, pairInfo);
        this.pairList.add(pairInfo);

        // 更新配对结算金额
        double currClearAmount = this.calcClearAmount(this.currRecord, pairNumber);
        double preClearAmount = this.calcClearAmount(preRecord, pairNumber);
        double addDiff = WeistockUtils.add(currClearAmount, preClearAmount);
        double currDiffAmount = this.currRecord.getDiffAmount() == null ? 0 : this.currRecord.getDiffAmount();
        this.currRecord.setDiffAmount(WeistockUtils.add(currDiffAmount, addDiff));

        // 修改变量
        this.currTradeNumber = this.currTradeNumber - pairNumber;
    }

    private void addPairToRecord(StockRecordBO record, RecordPairBO pair) {
        List<RecordPairBO> pairList = record.getPairList();
        if (pairList == null) {
            pairList = new ArrayList<>();
            record.setPairList(pairList);
        }
        pairList.add(pair);
    }

    private double calcClearAmount(StockRecordBO record, int pairNumber) {
        if (pairNumber == record.getTradeNumber()) {
            return record.getClearAmount();
        }
        return WeistockUtils.multi(WeistockUtils.divide(record.getClearAmount(), record.getTradeNumber()), pairNumber);
    }

    public int getCurrTradeNumber() {
        return this.currTradeNumber;
    }

    public void finishRecord() {
        if (this.pairList.size() > 0) {
            RecordPairBO currPair = new RecordPairBO();
            currPair.setIndex(this.pairIndex++);
            int totalNumber = 0;
            for (RecordPairBO prePair : this.pairList) {
                totalNumber += prePair.getNumber();
            }
            currPair.setNumber(totalNumber);
            this.addPairToRecord(this.currRecord, currPair);
        }
    }
}